<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Searching an Index - Zend Framework Manual</title>

    <link href="../css/shCore.css" rel="stylesheet" type="text/css" />
    <link href="../css/shThemeDefault.css" rel="stylesheet" type="text/css" />
    <link href="../css/styles.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Zend Framework</h1>
<h2>Programmer's Reference Guide</h2>
<ul>
    <li><a href="../en/zend.search.lucene.searching.html">Inglês (English)</a></li>
    <li><a href="../pt-br/zend.search.lucene.searching.html">Português Brasileiro (Brazilian Portuguese)</a></li>
</ul>
<table width="100%">
    <tr valign="top">
        <td width="85%">
            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="zend.search.lucene.index-creation.html">Construindo &Iacute;ndices</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="zend.search.lucene.html">Zend_Search_Lucene</a></span><br />
                        <span class="home"><a href="manual.html">Guia de Refer&ecirc;ncia do Programador</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="zend.search.lucene.query-language.html">Query Language</a></div>
                    </td>
                </tr>
            </table>
<hr />
<div id="zend.search.lucene.searching" class="section"><div class="info"><h1 class="title">Searching an Index</h1></div>
    

    <div class="section" id="zend.search.lucene.searching.query_building"><div class="info"><h1 class="title">Building Queries</h1></div>
        

        <p class="para">
            There are two ways to search the index. The first method uses
            query parser to construct a query from a string. The second is
            to programmatically create your own queries through the
            <span class="classname">Zend_Search_Lucene</span> <acronym class="acronym">API</acronym>.
        </p>

        <p class="para">
        Before choosing to use the provided query parser, please consider
        the following:

            <ol type="1">
                <li class="listitem">
                    <p class="para">
                        If you are programmatically creating a query string and then parsing
                        it with the query parser then you should consider building your queries
                        directly with the query <acronym class="acronym">API</acronym>. Generally speaking, the
                        query parser is designed for human-entered text, not for program-generated
                        text.
                    </p>
                </li>

                <li class="listitem">
                    <p class="para">
                        Untokenized fields are best added directly to queries and not through
                        the query parser. If a field&#039;s values are generated programmatically
                        by the application, then the query clauses for this field should also
                        be constructed programmatically.
                        An analyzer, which the query parser uses, is designed to convert
                        human-entered text to terms. Program-generated values, like dates,
                        keywords, etc., should be added with the query <acronym class="acronym">API</acronym>.
                    </p>
                </li>

                <li class="listitem">
                    <p class="para">
                        In a query form, fields that are general text should use the query parser.
                        All others, such as date ranges, keywords, etc., are better added directly
                        through the query <acronym class="acronym">API</acronym>. A field with a limited set of
                        values that can be specified with a pull-down menu should not be added to a
                        query string that is subsequently parsed but instead should be added as a
                        TermQuery clause.
                    </p>
                </li>

                <li class="listitem">
                    <p class="para">
                        Boolean queries allow the programmer to logically combine two or more
                        queries into new one. Thus it&#039;s the best way to add additional criteria to a
                        search defined by a query string.
                    </p>
                </li>
            </ol>
        </p>

        <p class="para">
            Both ways use the same <acronym class="acronym">API</acronym> method to search through the index:
        </p>

        <pre class="programlisting brush: php">
$index = Zend_Search_Lucene::open(&#039;/data/my_index&#039;);

$index-&gt;find($query);
</pre>


        <p class="para">
            The  <span class="methodname">Zend_Search_Lucene::find()</span> method determines the input type
            automatically and uses the query parser to construct an appropriate
            <span class="classname">Zend_Search_Lucene_Search_Query</span> object from an input of type
            string.
        </p>

        <p class="para">
            It is important to note that the query parser uses the standard analyzer to tokenize
            separate parts of query string. Thus all transformations which are applied to indexed
            text are also applied to query strings.
        </p>

        <p class="para">
            The standard analyzer may transform the query string to lower case for
            case-insensitivity, remove stop-words, and stem among other transformations.
        </p>

        <p class="para">
            The <acronym class="acronym">API</acronym> method doesn&#039;t transform or filter input terms in any way.
            It&#039;s therefore more suitable for computer generated or untokenized fields.
        </p>

        <div class="section" id="zend.search.lucene.searching.query_building.parsing"><div class="info"><h1 class="title">Query Parsing</h1></div>
            

            <p class="para">
                 <span class="methodname">Zend_Search_Lucene_Search_QueryParser::parse()</span> method may
                be used to parse query strings into query objects.
            </p>

            <p class="para">
                This query object may be used in query construction <acronym class="acronym">API</acronym> methods
                to combine user entered queries with programmatically generated queries.
            </p>

            <p class="para">
                Actually, in some cases it&#039;s the only way to search for values within untokenized
                fields:
            </p>

            <pre class="programlisting brush: php">
$userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr);

$pathTerm  = new Zend_Search_Lucene_Index_Term(
                     &#039;/data/doc_dir/&#039; . $filename, &#039;path&#039;
                 );
$pathQuery = new Zend_Search_Lucene_Search_Query_Term($pathTerm);

$query = new Zend_Search_Lucene_Search_Query_Boolean();
$query-&gt;addSubquery($userQuery, true /* required */);
$query-&gt;addSubquery($pathQuery, true /* required */);

$hits = $index-&gt;find($query);
</pre>


            <p class="para">
                 <span class="methodname">Zend_Search_Lucene_Search_QueryParser::parse()</span> method also
                takes an optional encoding parameter, which can specify query string encoding:
            </p>

            <pre class="programlisting brush: php">
$userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr,
                                                          &#039;iso-8859-5&#039;);
</pre>


            <p class="para">
                If the encoding parameter is omitted, then current locale is used.
            </p>

            <p class="para">
                It&#039;s also possible to specify the default query string encoding with
                 <span class="methodname">Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding()</span>
                method:
            </p>

            <pre class="programlisting brush: php">
Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding(&#039;iso-8859-5&#039;);
...
$userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr);
</pre>


            <p class="para">
                 <span class="methodname">Zend_Search_Lucene_Search_QueryParser::getDefaultEncoding()</span>
                returns the current default query string encoding (the empty string means &quot;current
                locale&quot;).
            </p>
        </div>
    </div>

    <div class="section" id="zend.search.lucene.searching.results"><div class="info"><h1 class="title">Search Results</h1></div>
        

        <p class="para">
            The search result is an array of
            <span class="classname">Zend_Search_Lucene_Search_QueryHit</span> objects. Each of these has two
            properties: <code class="code">$hit-&gt;id</code> is a document number within the index and
            <code class="code">$hit-&gt;score</code> is a score of the hit in a search result. The results are
            ordered by score (descending from highest score).
        </p>

        <p class="para">
            The <span class="classname">Zend_Search_Lucene_Search_QueryHit</span> object also exposes each
            field of the <span class="classname">Zend_Search_Lucene_Document</span> found in the search as a
            property of the hit. In the following example, a hit is returned with two fields from
            the corresponding document: title and author.
        </p>

        <pre class="programlisting brush: php">
$index = Zend_Search_Lucene::open(&#039;/data/my_index&#039;);

$hits = $index-&gt;find($query);

foreach ($hits as $hit) {
    echo $hit-&gt;score;
    echo $hit-&gt;title;
    echo $hit-&gt;author;
}
</pre>


        <p class="para">
            Stored fields are always returned in UTF-8 encoding.
        </p>

        <p class="para">
            Optionally, the original <span class="classname">Zend_Search_Lucene_Document</span> object can
            be returned from the <span class="classname">Zend_Search_Lucene_Search_QueryHit</span>.
            You can retrieve stored parts of the document by using the
             <span class="methodname">getDocument()</span> method of the index object and then get them by
             <span class="methodname">getFieldValue()</span> method:
        </p>

        <pre class="programlisting brush: php">
$index = Zend_Search_Lucene::open(&#039;/data/my_index&#039;);

$hits = $index-&gt;find($query);
foreach ($hits as $hit) {
    // return Zend_Search_Lucene_Document object for this hit
    echo $document = $hit-&gt;getDocument();

    // return a Zend_Search_Lucene_Field object
    // from the Zend_Search_Lucene_Document
    echo $document-&gt;getField(&#039;title&#039;);

    // return the string value of the Zend_Search_Lucene_Field object
    echo $document-&gt;getFieldValue(&#039;title&#039;);

    // same as getFieldValue()
    echo $document-&gt;title;
}
</pre>


        <p class="para">
            The fields available from the <span class="classname">Zend_Search_Lucene_Document</span> object
            are determined at the time of indexing. The document fields are either indexed, or
            index and stored, in the document by the indexing application
            (e.g. LuceneIndexCreation.jar).
        </p>

        <p class="para">
            Note that the document identity (&#039;path&#039; in our example) is also stored
            in the index and must be retrieved from it.
        </p>
    </div>

    <div class="section" id="zend.search.lucene.searching.results-limiting"><div class="info"><h1 class="title">Limiting the Result Set</h1></div>
        

        <p class="para">
            The most computationally expensive part of searching is score calculation. It may take
            several seconds for large result sets (tens of thousands of hits).
        </p>

        <p class="para">
            <span class="classname">Zend_Search_Lucene</span> gives the possibility to limit result set size
            with  <span class="methodname">getResultSetLimit()</span> and
             <span class="methodname">setResultSetLimit()</span> methods:
        </p>

        <pre class="programlisting brush: php">
$currentResultSetLimit = Zend_Search_Lucene::getResultSetLimit();

Zend_Search_Lucene::setResultSetLimit($newLimit);
</pre>


        <p class="para">
            The default value of 0 means &#039;no limit&#039;.
        </p>

        <p class="para">
            It doesn&#039;t give the &#039;best N&#039; results, but only the &#039;first N&#039;

            <a href="#fnid1" name="fn1"><sup>[1]</sup></a>
                
            .
        </p>
    </div>

    <div class="section" id="zend.search.lucene.searching.results-scoring"><div class="info"><h1 class="title">Results Scoring</h1></div>
        

        <p class="para">
            <span class="classname">Zend_Search_Lucene</span> uses the same scoring algorithms as Java
            Lucene. All hits in the search result are ordered by score by default. Hits with greater
            score come first, and documents having higher scores should match the query more
            precisely than documents having lower scores.
        </p>

        <p class="para">
            Roughly speaking, search hits that contain the searched term or phrase more frequently
            will have a higher score.
        </p>

        <p class="para">
            A hit&#039;s score can be retrieved by accessing the <code class="code">score</code> property of the hit:
        </p>

        <pre class="programlisting brush: php">
$hits = $index-&gt;find($query);

foreach ($hits as $hit) {
    echo $hit-&gt;id;
    echo $hit-&gt;score;
}
</pre>


        <p class="para">
            The <span class="classname">Zend_Search_Lucene_Search_Similarity</span> class is used to
            calculate the score for each hit. See <a href="zend.search.lucene.extending.html#zend.search.lucene.extending.scoring" class="link">Extensibility. Scoring
                Algorithms</a> section for details.
        </p>
    </div>

    <div class="section" id="zend.search.lucene.searching.sorting"><div class="info"><h1 class="title">Search Result Sorting</h1></div>
        

        <p class="para">
            By default, the search results are ordered by score. The programmer can change this
            behavior by setting a sort field (or a list of fields), sort type and sort order
            parameters.
        </p>

        <p class="para">
            <code class="code">$index-&gt;find()</code> call may take several optional parameters:
        </p>

        <pre class="programlisting brush: php">
$index-&gt;find($query [, $sortField [, $sortType [, $sortOrder]]]
                    [, $sortField2 [, $sortType [, $sortOrder]]]
             ...);
</pre>


        <p class="para">
             A name of stored field by which to sort result should be passed as the
             <var class="varname">$sortField</var> parameter.
        </p>

        <p class="para">
            <var class="varname">$sortType</var> may be omitted or take the following enumerated values:
            <b><tt>SORT_REGULAR</tt></b> (compare items normally- default value),
            <b><tt>SORT_NUMERIC</tt></b> (compare items numerically),
            <b><tt>SORT_STRING</tt></b> (compare items as strings).
        </p>

        <p class="para">
            <var class="varname">$sortOrder</var> may be omitted or take the following enumerated values:
            <b><tt>SORT_ASC</tt></b> (sort in ascending order- default value),
            <b><tt>SORT_DESC</tt></b> (sort in descending order).
        </p>

        <p class="para">
            Examples:
        </p>

        <pre class="programlisting brush: php">
$index-&gt;find($query, &#039;quantity&#039;, SORT_NUMERIC, SORT_DESC);
</pre>


        <pre class="programlisting brush: php">
$index-&gt;find($query, &#039;fname&#039;, SORT_STRING, &#039;lname&#039;, SORT_STRING);
</pre>


        <pre class="programlisting brush: php">
$index-&gt;find($query, &#039;name&#039;, SORT_STRING, &#039;quantity&#039;, SORT_NUMERIC, SORT_DESC);
</pre>


        <p class="para">
            Please use caution when using a non-default search order; the query needs to retrieve
            documents completely from an index, which may dramatically reduce search performance.
        </p>
    </div>

    <div class="section" id="zend.search.lucene.searching.highlighting"><div class="info"><h1 class="title">Search Results Highlighting</h1></div>
        

        <p class="para">
            <span class="classname">Zend_Search_Lucene</span> provides two options for search results
            highlighting.
        </p>

        <p class="para">
            The first one is utilizing <span class="classname">Zend_Search_Lucene_Document_Html</span> class
            (see <a href="zend.search.lucene.overview.html#zend.search.lucene.index-creation.html-documents" class="link">HTML documents
                section</a> for details) using the following methods:
        </p>

        <pre class="programlisting brush: php">
/**
 * Highlight text with specified color
 *
 * @param string|array $words
 * @param string $colour
 * @return string
 */
public function highlight($words, $colour = &#039;#66ffff&#039;);
</pre>


        <pre class="programlisting brush: php">
/**
 * Highlight text using specified View helper or callback function.
 *
 * @param string|array $words  Words to highlight. Words could be organized
                               using the array or string.
 * @param callback $callback   Callback method, used to transform
                               (highlighting) text.
 * @param array    $params     Array of additionall callback parameters passed
                               through into it (first non-optional parameter
                               is an HTML fragment for highlighting)
 * @return string
 * @throws Zend_Search_Lucene_Exception
 */
public function highlightExtended($words, $callback, $params = array())
</pre>


        <p class="para">
            To customize highlighting behavior use  <span class="methodname">highlightExtended()</span>
            method with specified callback, which takes one or more parameters

            <a href="#fnid2" name="fn2"><sup>[2]</sup></a>
                <acronym class="acronym">HTML</acronym><acronym class="acronym">HTML</acronym>
            
            , or extend <span class="classname">Zend_Search_Lucene_Document_Html</span> class and redefine
             <span class="methodname">applyColour($stringToHighlight, $colour)</span> method used as a
            default highlighting callback.

            <a href="#fnid3" name="fn3"><sup>[3]</sup></a>
                <acronym class="acronym">HTML</acronym><acronym class="acronym">XHTML</acronym>
            
        </p>

        <p class="para">
            <a href="zend.view.helpers.html" class="link">View helpers</a> also can be used as callbacks in
            context of view script:
        </p>

        <pre class="programlisting brush: php">
$doc-&gt;highlightExtended(&#039;word1 word2 word3...&#039;, array($this, &#039;myViewHelper&#039;));
</pre>


        <p class="para">
            The result of highlighting operation is retrieved by
            <code class="code">Zend_Search_Lucene_Document_Html-&gt;getHTML()</code> method.
        </p>

        <blockquote class="note"><p><b class="note">Note</b>: 
            <p class="para">
                Highlighting is performed in terms of current analyzer. So all forms of the word(s)
                recognized by analyzer are highlighted.
            </p>

            <p class="para">
                E.g. if current analyzer is case insensitive and we request to highlight &#039;text&#039;
                word, then &#039;text&#039;, &#039;Text&#039;, &#039;TEXT&#039; and other case combinations will be highlighted.
            </p>

            <p class="para">
                In the same way, if current analyzer supports stemming and we request to highlight
                &#039;indexed&#039;, then &#039;index&#039;, &#039;indexing&#039;, &#039;indices&#039; and other word forms will be
                highlighted.
            </p>

            <p class="para">
                On the other hand, if word is skipped by current analyzer (e.g. if short words
                filter is applied to the analyzer), then nothing will be highlighted.
            </p>
        </p></blockquote>

        <p class="para">
            The second option is to use
            <code class="code">Zend_Search_Lucene_Search_Query-&gt;highlightMatches(string $inputHTML[,
                $defaultEncoding = &#039;UTF-8&#039;[,
                Zend_Search_Lucene_Search_Highlighter_Interface $highlighter]])</code> method:
        </p>

        <pre class="programlisting brush: php">
$query = Zend_Search_Lucene_Search_QueryParser::parse($queryStr);
$highlightedHTML = $query-&gt;highlightMatches($sourceHTML);
</pre>


        <p class="para">
            Optional second parameter is a default <acronym class="acronym">HTML</acronym> document encoding. It&#039;s
            used if encoding is not specified using Content-type HTTP-EQUIV meta tag.
        </p>

        <p class="para">
            Optional third parameter is a highlighter object which has to implement
            <span class="classname">Zend_Search_Lucene_Search_Highlighter_Interface</span> interface:
        </p>

        <pre class="programlisting brush: php">
interface Zend_Search_Lucene_Search_Highlighter_Interface
{
    /**
     * Set document for highlighting.
     *
     * @param Zend_Search_Lucene_Document_Html $document
     */
    public function setDocument(Zend_Search_Lucene_Document_Html $document);

    /**
     * Get document for highlighting.
     *
     * @return Zend_Search_Lucene_Document_Html $document
     */
    public function getDocument();

    /**
     * Highlight specified words (method is invoked once per subquery)
     *
     * @param string|array $words  Words to highlight. They could be
                                   organized using the array or string.
     */
    public function highlight($words);
}
</pre>


        <p class="para">
            Where <span class="classname">Zend_Search_Lucene_Document_Html</span> object is an object
            constructed from the source <acronym class="acronym">HTML</acronym> provided to the
            <span class="classname">Zend_Search_Lucene_Search_Query-&gt;highlightMatches()</span> method.
        </p>

        <p class="para">
            If <var class="varname">$highlighter</var> parameter is omitted, then
            <span class="classname">Zend_Search_Lucene_Search_Highlighter_Default</span> object is
            instantiated and used.
        </p>

        <p class="para">
            Highlighter  <span class="methodname">highlight()</span> method is invoked once per subquery, so
            it has an ability to differentiate highlighting for them.
        </p>

        <p class="para">
            Actually, default highlighter does this walking through predefined color table. So you
            can implement your own highlighter or just extend the default and redefine color table.
        </p>

        <p class="para">
            <code class="code">Zend_Search_Lucene_Search_Query-&gt;htmlFragmentHighlightMatches()</code> has similar
            behavior. The only difference is that it takes as an input and returns
            <acronym class="acronym">HTML</acronym> fragment without &lt;&gt;HTML&gt;, &lt;HEAD&gt;, &lt;BODY&gt; tags.
            Nevertheless, fragment is automatically transformed to valid <acronym class="acronym">XHTML</acronym>.
        </p>
    </div>
<div class="footnote"><a name="fnid1" href="#fn1"><sup>[1]</sup></a><span class="para footnote">
                    Returned hits are still ordered by score or by the specified order, if given.
                </span></div>
<div class="footnote"><a name="fnid2" href="#fn2"><sup>[2]</sup></a><span class="para footnote">
                    The first is an  fragment for highlighting and others are
                    callback behavior dependent. Returned value is a highlighted
                     fragment.
                </span></div>
<div class="footnote"><a name="fnid3" href="#fn3"><sup>[3]</sup></a><span class="para footnote">
                    In both cases returned  is automatically transformed into
                    valid .
                </span></div>
</div>
        <hr />

            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="zend.search.lucene.index-creation.html">Construindo &Iacute;ndices</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="zend.search.lucene.html">Zend_Search_Lucene</a></span><br />
                        <span class="home"><a href="manual.html">Guia de Refer&ecirc;ncia do Programador</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="zend.search.lucene.query-language.html">Query Language</a></div>
                    </td>
                </tr>
            </table>
</td>
        <td style="font-size: smaller;" width="15%"> <style type="text/css">
#leftbar {
	float: left;
	width: 186px;
	padding: 5px;
	font-size: smaller;
}
ul.toc {
	margin: 0px 5px 5px 5px;
	padding: 0px;
}
ul.toc li {
	font-size: 85%;
	margin: 1px 0 1px 1px;
	padding: 1px 0 1px 11px;
	list-style-type: none;
	background-repeat: no-repeat;
	background-position: center left;
}
ul.toc li.header {
	font-size: 115%;
	padding: 5px 0px 5px 11px;
	border-bottom: 1px solid #cccccc;
	margin-bottom: 5px;
}
ul.toc li.active {
	font-weight: bold;
}
ul.toc li a {
	text-decoration: none;
}
ul.toc li a:hover {
	text-decoration: underline;
}
</style>
 <ul class="toc">
  <li class="header home"><a href="manual.html">Guia de Refer&ecirc;ncia do Programador</a></li>
  <li class="header up"><a href="manual.html">Guia de Refer&ecirc;ncia do Programador</a></li>
  <li class="header up"><a href="reference.html">Refer&ecirc;ncia do Zend Framework</a></li>
  <li class="header up"><a href="zend.search.lucene.html">Zend_Search_Lucene</a></li>
  <li><a href="zend.search.lucene.overview.html">Resumo</a></li>
  <li><a href="zend.search.lucene.index-creation.html">Construindo &Iacute;ndices</a></li>
  <li class="active"><a href="zend.search.lucene.searching.html">Searching an Index</a></li>
  <li><a href="zend.search.lucene.query-language.html">Query Language</a></li>
  <li><a href="zend.search.lucene.query-api.html">Query Construction API</a></li>
  <li><a href="zend.search.lucene.charset.html">Conjunto de Caracteres</a></li>
  <li><a href="zend.search.lucene.extending.html">Extensibilidade</a></li>
  <li><a href="zend.search.lucene.java-lucene.html">Interoperando com Java Lucene</a></li>
  <li><a href="zend.search.lucene.advanced.html">Avan&ccedil;ado</a></li>
  <li><a href="zend.search.lucene.best-practice.html">Best Practices</a></li>
 </ul>
 </td>
    </tr>
</table>

<script type="text/javascript" src="../js/shCore.js"></script>
<script type="text/javascript" src="../js/shAutoloader.js"></script>
<script type="text/javascript" src="../js/main.js"></script>

</body>
</html>